using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace edu.stanford.hci.ideas
{
    
    public class AudioLevel
    {

        private double _audio_level;
        private byte[] m_RecBuffer;
       
        private List<AudioListener> audioListeners = new List<AudioListener>();

        public AudioLevel()
        {
            _audio_level = 0;
            WaveLib.WaveFormat fmt = new WaveLib.WaveFormat(8192, 8, 2);
            WaveLib.WaveInRecorder m_Recorder = new WaveLib.WaveInRecorder(0, fmt, 512, 3, new WaveLib.BufferDoneEventHandler(DataArrived));
        }


        private void DataArrived(IntPtr data, int size)
        {
            if (m_RecBuffer == null || m_RecBuffer.Length < size)
                m_RecBuffer = new byte[size];
            System.Runtime.InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size);
#if FALSE
            byte maxVal = 0;
            for (int i = 0; i < size; i+= 2)
            {
                maxVal = m_RecBuffer[i] > maxVal ? m_RecBuffer[i] : maxVal;
            }

            _audio_level = (double)maxVal / (255);
#endif
            FFT myFFT = new FFT();
            const int samplingRate = 8192;
            double[] inputFFT = new double[samplingRate];
            for (int i = 0; i < size; i++)
            {
                inputFFT[i] = m_RecBuffer[i];
            }
            ulong fund_freq = myFFT.ComplexFFT(inputFFT, (ulong) size, samplingRate, 1);
            double totalAmp = 0.0;
            for (int i = 0; i < samplingRate; i++)
            {
                // integrating the modulus of the FFT over all frequencies to get
                // the power of the signal...
                double amplitude = myFFT.GetAmplitude(i);
                totalAmp += amplitude;
            }
            System.Console.WriteLine("Integral of FFT values is: " + totalAmp);
#if FALSE
            double MIN_AMP = 1000000.0;// xxx - need to set this for the iRoom
            double MAX_AMP= 10000000.0; // xxx - need to set this for the iRoom
            if (totalAmp < MIN_AMP) totalAmp = MIN_AMP;
            if (totalAmp > MAX_AMP) totalAmp = MAX_AMP;
            _audio_level = (totalAmp - MIN_AMP) / (MAX_AMP - MIN_AMP);
#endif
            _audio_level = totalAmp;
            fireAudioEvent();
            //System.Console.WriteLine("Audio: " + _audio_level);
        }

        public void addAudioListener(AudioListener listener)
        {
            audioListeners.Add(listener);
        }

        public void fireAudioEvent()
        {
            AudioEvent e = new AudioEvent(_audio_level);
            foreach (AudioListener listener in audioListeners)
            {
                listener.audioEvent(e);
            }
        }
    }

    public class AudioEvent
    {
        private double _level =0.0;

        public AudioEvent(double level)
        {
            _level = level;
        }

        public AudioEvent()
        {
        }
        public double getLevel() 
        {
            return _level;
        }

    }

    public interface AudioListener
    {
        void audioEvent(AudioEvent e);
    }
}
